home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / terminal / tsth_140 / con_filt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-30  |  7.9 KB  |  245 lines

  1.  
  2. /* CON_FILT.EXE example file for TstHost.
  3.    compile with BCC CON_FILT.C
  4. -------------------------------------------------------------------------------
  5.    NOTE: if you decide to modify this code, please read the CFILT_??.DOC file
  6.    to ensure compatibility with the others md2 filtering and password decoding
  7.    sistem.
  8. -------------------------------------------------------------------------------
  9.    This server use the CON_FILT.PSW file, that have this format:
  10.    Every empty line, or line that start with the '#' are ignored.
  11.    The first valid line are password request prompt.
  12.    The second line is the filter mode, 0 for OPEN SYTEM, 1 for CLOSED SYSTEM.
  13.    The others line are the callsign, without ssid, flag and its password, like:
  14.    CALL FLAG PASSWORD
  15.    CALL FLAG PASSWORD
  16.    ... etc.
  17.  
  18.      NOTE: PASSWORD is not needed if FLAG=0
  19.  
  20.  
  21.    OPEN SYSTEM MODE
  22.    If the call is not declared in the con_filt.psw file, the user will be
  23.    connected without password request, userful for bbs forward, or user that
  24.    do not want password.
  25.    If a callsign is declared:
  26.      if FLAG=0, the callsign is excluded, disconneted.
  27.      if FLAG=1, the callsign is connected after the password request.
  28.  
  29.    CLOSE SYSTEM MODE
  30.    Only the callsign declared in the con_filt.psw may access to the system,
  31.    the other will be disconneted.
  32.    For declared callsign:
  33.      if FLAG=0, the connection is accepted without password request.
  34.      if FLAG=1, the connection is accepted, but the password will be requested.
  35.  
  36. >  Prompt must be long at most 80 characters
  37. >  Password my be long at most 255 characters, without space.
  38. >  This program, if renamed C_FILTER.EXE, run also under FBB 5.15a and upper
  39.  
  40.    The server use a temporary file XXXXXX.CFT, where XXXXXX is the callsign of
  41.    the user, to store the calculated password and date time of any unsuccesful
  42.    logon; you do not need to touch this file, all management will be done by
  43.    con_filt; the temporary file will be automatically deleted when not more
  44.    needed.
  45.  
  46.    The server use both the standard 5 letters password and the MD2 (c)RSA
  47.    alghoritm. The user may answer in standard or md2 mode, the server will
  48.    decode automatically the corrected mode.
  49.  
  50.    The line arguments given to the CON_FILT from TstHost are :
  51. - Callsign (format as IK1GKJ).
  52. - Level number (0 is the first time, up to 255).
  53. - reserved, always 0
  54. - reserved, always 0
  55. - reserved, always 0
  56. - reserved, always 1
  57. - Received data (each word is a new argument).
  58.  
  59.  The CON_FILT program end with an exit value. This value tells the PMS what do:
  60. - 0 accept connection.
  61. - 1 the program will be called again and the level number is incremented.
  62. - 2 the user will be disconnected.
  63.  
  64. */
  65.  
  66. #include <stdio.h>
  67. #include <stdlib.h>
  68. #include <io.h>
  69. #include <time.h>
  70. #include <string.h>
  71. #include "md2code.c"
  72.  
  73. void error(void);         /* this function exit with a value of 2 */
  74.  
  75. char call[7]="",
  76.      call1[7]="",
  77.      buffer[400]="",
  78.      tmp[100]="",
  79.      UserFile[20]="",
  80.      BbsPrompt[81]="",
  81.      Password[256]="",
  82.      ExcludeMessage[]="\n*** Sorry, you can not access to this system.\n";
  83. int  pass[5],
  84.      Port,
  85.      level,
  86.      SystemMode,
  87.      UserFlag;
  88. long timet;
  89. FILE *pf;
  90. unsigned char MD2digest[16];
  91. MD2_CTX context;
  92.  
  93. main(int ac, char **av)
  94. {
  95.  
  96. /* FIRST GET LEVEL NUMBER AND THE CALLSIGN, MAKE USER FILE NAME */
  97. int i=0,found=0,jj;
  98. if(ac<7) error();
  99. level=atoi(av[2]);
  100.  
  101. Port=atoi(av[6]);    /* THIS AND NEXT INSTRUCTION ARE ONLY FOR FBB */
  102. if(!Port) return 0;    /* PORT 0 IS CONSOLLE UNDER FBB */
  103.  
  104. if(sscanf(av[1],"%6[a-zA-Z0-9]",call)!=1) error();
  105. sprintf(UserFile,"%s.CFT",call);            
  106.  
  107. /* AT CONNECTION, READ IN CON_FILT.PSW, TO SEARCH FOR THE USER CALLSIGN
  108.    THE FIRST VALID LINE IN THE FILE ARE THE PMS REQUEST PASSWORD PROMPT
  109.    NEXT THE SISTEM OPEN/CLOSE MODE
  110.    NEXT THE USER CALL FLAG PASSWORD */ 
  111. if(!level)
  112.     {
  113.     if((pf=fopen("CON_FILT.PSW","rt"))==NULL) error();
  114.         i=0;
  115.     while(fgets(buffer,399,pf))
  116.         {
  117.         if(*buffer==0 || *buffer=='\n' || *buffer=='#') continue;
  118.         if(!i)    {
  119.             if(sscanf(buffer," %80[^\n]",BbsPrompt)!=1) error();
  120.             i++;
  121.             continue;
  122.             }
  123.         if(i==1){
  124.             if(sscanf(buffer," %d",&SystemMode)!=1) error();
  125.             i++;
  126.             continue;
  127.             }
  128.         jj=sscanf(buffer," %6[a-zA-Z0-9] %d %255s",call1,&UserFlag,Password);
  129.         if(jj<2 || (jj<3 && UserFlag))    error();
  130.         if(stricmp(call,call1)) continue;
  131.         found=1;
  132.         break;
  133.         }
  134.     if(ferror(pf)) error();
  135.     fclose(pf);
  136.     if(!SystemMode)        /* IN OPEN SYSTEM MODE */
  137.         {            /* CALL NOT FOUND, ACCEPT CONNECTION */
  138.         if(!found) exit(0);    /* WITHOUT PASSWORD */
  139.         if(!UserFlag)        /* IF FLAG=0, CALLSIGN IS EXCLUDED */
  140.             {
  141.             puts(ExcludeMessage);
  142.             exit(2);    /* OTHERWISE ASK FOR THE PASSWORD */
  143.             }
  144.         }
  145.     else    {        /* IN CLOSED SYSTEM MODE */
  146.         if(!found)        /* CALL NOT FOUND, DISCONNECT */
  147.             {
  148.             puts(ExcludeMessage);
  149.             exit(2);
  150.             }
  151.         if(!UserFlag) exit(0);    /* FLAG=0, CONNECT WITHOUT PASSWORD */
  152.         }            /* OTHERWISE ASK FOT THE PASSWORD */
  153.  
  154.     /* NEXT CALCULATE 5 RANDOM NUMERS FOR STANDARD PASSWORD */
  155.     level=strlen(Password);
  156.     randomize();
  157.     for(i=0;i<5;i++) pass[i]=random(level);
  158.     
  159.     /* NEXT MAKE THE MD2 PASSWORD, FIRST GET CURRENT DATE TIME, THIS
  160.        VALUE IS ALSO USED TO MAKE AN UNIQUE 10 CHARACTERS STRING.
  161.        TO THOSE 10 CHAR WILL BE ADD THE USERS PASSWORD,
  162.        THE RESULTING STRING WILL BE PASSED TO THE MD2 ALGHORITM */
  163.     timet=time(NULL);
  164.     sprintf(buffer,"%010.10ld%s",timet,Password);
  165.     MD2Init(&context);
  166.     MD2Update(&context,(unsigned char *)buffer,level+10);
  167.     MD2Final(MD2digest,&context);
  168.     
  169.     /* NOW CONVERT 16 MD2 CHARACTERS TO LITERAL 32 BYTE HEX NOTATION */
  170.     for(i=0;i<16;i++) sprintf(&tmp[i*2],"%02x",MD2digest[i]);
  171.  
  172.     /* OPEN THE USER FILENAME, IF THE FILE DO NOT EXIST, WILL BE CREATED
  173.        OTHERWISE WILL BE OPENED FOR READ AND WRITE */
  174.     if((pf=fopen(UserFile,access(UserFile,0)?"wt":"rt+"))==NULL) error();
  175.     
  176.     /* NOTE THAT THE FIRST LINE OF THE FILE HAVE ALWAYS THE SAME SIZE, THIS
  177.        LINE IS USED TO STORE THE CALCULATED ANSWER, FIRST THE 5 LETTER MODE
  178.        A SPACE, AND NEXT THE 32 BYTE MD2 */
  179.     rewind(pf);
  180.     fprintf(pf,"%c%c%c%c%c %s\n",Password[pass[0]],Password[pass[1]],
  181.         Password[pass[2]],Password[pass[3]],Password[pass[4]],tmp);
  182.  
  183.     /* NOW GO TO THE END OF FILE, AND STORE THE DATE TIME FOR THIS LOGON */
  184.     fseek(pf,0L,SEEK_END);
  185.     fprintf(pf,"%s",ctime(&timet));
  186.     if(ferror(pf)) error();
  187.     fclose(pf);
  188.  
  189.     /* AT THE END, SEND TO THE USER THE PROMPT, THE 5 NUMBERS, AND MD2
  190.        REQUEST PASSWORD */
  191.     printf("\n%s %d %d %d %d %d [%010.10ld]\n",
  192.       BbsPrompt,pass[0]+1,pass[1]+1,pass[2]+1,pass[3]+1,pass[4]+1,timet);
  193.     return 1;    /* CON_FILT MUST BE CALLED AGAIN */
  194.     }
  195.  
  196.  
  197. /* LEVEL 1, CON_FILT RECEIVE THE PASSWORD ANSWER FROM THE USER */
  198.  
  199. /* FIRST OPEN THE USER FILE AND RETRIEVE THE 5 LETTER AND MD2 CORRECTED DATA */
  200. if((pf=fopen(UserFile,"rt"))==NULL) error();
  201. if(!fgets(buffer,80,pf)) error();
  202. if(sscanf(buffer," %5s %32s",BbsPrompt,tmp)!=2) error();
  203. i=0;
  204.  
  205. /* IF USER ANSWER IS EXACTLY 32 BYTE LONG, TREAT THE DATA LIKE MD2, OTHERWISE
  206.    LIKE A 5 LETTERS PASSWORD */
  207. if(strlen(av[7])==32) i=stricmp(av[7],tmp);                    /* yes, use md2 password, ignoring case */
  208. else    i=strcmp(av[7],BbsPrompt);
  209.  
  210. /* IF INCORRECT PASSWORD, DISCONNECT THE USER, CLOSE BUT NOT DELETE THE
  211.    USERS FILE */
  212. if(i)    {
  213.     puts("\n*** Password error.\n");
  214.     fclose(pf);
  215.     return 2;
  216.     }
  217.  
  218. /* RIGHT PASSWORD, BEFORE DELETE THE USER FILE, SEND TO THE USER ALL
  219.    UNSUCCESFUL LOGON REGISTERED IN THE FILE (IF EXIST) */
  220.    
  221. /* REMEMBER THAT THE LAST LINE IN THE FILE IS >THIS CONNECTION TIME<
  222.    AND MUST NOT BE SEND, SINCE THIS CONNETCTION WAS SUCCESFUL */
  223. fgets(tmp,80,pf);
  224. while(fgets(buffer,80,pf))
  225.     {
  226.     if(level)
  227.     {
  228.     level=0;
  229.     puts("\n*** WARNING -> Attempt to connect and password failure on:");
  230.     }
  231.     printf(tmp);
  232.     strcpy(tmp,buffer);
  233.     }
  234. puts("");
  235. fclose(pf);    
  236. unlink(UserFile);
  237. return 0;
  238. }
  239.  
  240. void error(void)
  241. {
  242. puts("\n*** Connection filtering: System error.\n");
  243. exit(2);
  244. }
  245.